/*
 * Copyright 2003-2007 (c) Live Media Pty Ltd. <argot@einet.com.au> 
 *
 * This software is licensed under the Argot Public License 
 * which may be found in the file LICENSE distributed 
 * with this software.
 *
 * More information about this license can be found at
 * http://www.einet.com.au/License
 * 
 * The Developer of this software is Live Media Pty Ltd,
 * PO Box 4591, Melbourne 3001, Australia.  The license is subject 
 * to the law of Victoria, Australia, and subject to exclusive 
 * jurisdiction of the Victorian courts.
 */

package com.colony.remote.rpc;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import com.colony.remote.RemoteException;

public class RpcMetaSkeleton
implements RpcDelegate
{
	/**
	 * A helper class used to proces a request and invoke a proxy
	 * object.
	 * 
	 * @param request
	 * @throws SomException
	 */
	public void processRequest( RpcMetaMethodRequest request, Object target )
	throws RemoteException
	{
		// Setup the objects used to invoke the request.
		Object[] args = request.getArguments();
				
		Method method = request.getMetaMethod().getMethod();		

		if ( method == null )
			throw new RemoteException( "NativeMethod not found" );
			
		invoke( request, target, method, args );
	}
	
	/**
	 * This is a helper function used to invoke a function and catch
	 * any exceptions.
	 * 
	 * @param request
	 * @param method
	 * @param args
	 * @throws SomException
	 */
	private void invoke( RpcMetaMethodRequest request, Object object, Method method, Object[] args )
	throws RemoteException
	{
		Object ret = null;
		try
		{
			// Invoke the request.
			ret = method.invoke( object, args );
		}
		catch (IllegalAccessException e )
		{
			request.setException( e );
		}
		catch (InvocationTargetException e )
		{
			request.setException( e.getTargetException() );
			//e.getTargetException().printStackTrace();
			return;
		}

		// If we got a return value.  Push it onto the stack.
		if ( method.getReturnType() != void.class )
		{		
			//TypeMap map = request.getTypeMap();
			// 6/12/2003 - This is a problem.  If the return type is
			// polymorphic then the object will be serialised as the
			// base class, not the full polymorphic type.
			//int id = map.getId( method.getReturnType() );
			//int id = map.getId( ret.getClass() );
			if ( !method.getReturnType().isAssignableFrom( ret.getClass() ))
			{
				//System.out.println( "NvmSkeleton. possibly bad return value");
				//System.out.println( "Method return type: " + method.getReturnType().getName() );
				//System.out.println( "Actual Return: " + ret.getClass().getName() );
			}
			//request.push( id, ret );
			request.setReturnValue( ret );
		}			
	}

}
